package com.xiongjie.keycloakAuth;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.oauth2.OAuth2Auth;
import io.vertx.ext.auth.oauth2.OAuth2FlowType;
import io.vertx.ext.auth.oauth2.providers.KeycloakAuth;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.api.RequestParameters;
import io.vertx.ext.web.api.contract.openapi3.OpenAPI3RouterFactory;

public class KeycloakAuthVertx extends AbstractVerticle {

    @Override
    public void start() {
        //创建keycloakAuth对象,其中resource和secret可以去keycloak服务器的Clients按钮查询。一般使用api-gateway
        JsonObject config = new JsonObject()
                .put("resource", "api-gateway")
                .put("realm", "9999")
                .put("auth-server-url", "http://192.168.1.14:8282/auth")
                .put("credentials", new JsonObject()
                        .put("secret", "e26c0a8a-4955-4d26-a820-4f11f7ed3eb3"));
        OAuth2Auth oauth2 = KeycloakAuth.create(vertx, OAuth2FlowType.PASSWORD, config);

        Router router = Router.router(vertx);
        OpenAPI3RouterFactory.create(vertx, "keycloakAuthOpenApi.yml", ar -> {
            if (ar.succeeded()) {
                OpenAPI3RouterFactory routerFactory = ar.result();

                routerFactory.addHandlerByOperationId("keycloakAuth", context -> {
                    RequestParameters params = context.get("parsedParameters");
                    JsonObject json = params.body().getJsonObject();

                    //进行keycloak授权认证
                    oauth2.authenticate(json, auth -> {
                        if (auth.succeeded()) {
                            System.out.println("使用keycloak授权访问成功！！！");
                            context.response()
                                    .putHeader("content-type", "application/json")
                                    .end(auth.result().principal().encode());
                        } else {
                            System.out.println("使用keycloak授权访问失败：" + auth.cause().getMessage());
                            context.response()
                                    .setStatusCode(401)
                                    .putHeader("content-type", "application/json")
                                    .end(new JsonObject()
                                            .put("title", "认证失败")
                                            .put("message", "请检查用户名，密码和公司是否正确")
                                            .encode());
                        }
                    });
                });

                router.mountSubRouter("/xj", routerFactory.getRouter());
                vertx.createHttpServer()
                        .requestHandler(router)
                        .listen(8888);
            } else {
                System.out.println("加载api文件失败：" + ar.cause());
            }
        });
    }
}
